/*
    Copyright 2010-2011 Patrik Jonsson, sunrise@familjenjonsson.org

    This file is part of Sunrise.

    Sunrise is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    Sunrise is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Sunrise.  If not, see <http://www.gnu.org/licenses/>.

*/

/** \file 

    Declaration of class monitor which displays a progress
    monitor image as shooting progresses. */

// $Id$

#ifndef __monitor__
#define __monitor__


#include "emergence.h"
#include "config.h"

namespace mcrx {
  class monitor;
};

#ifdef WITH_X11

#include <boost/thread/thread.hpp>
#include <vector>
#include <X11/Xlib.h>

/** The monitor class keeps references to images and runs a thread
    which displays them in an X11 window. This can be used to monitor
    the progress of the shooting. */
class mcrx::monitor {
private:
  bool modified_;
  /// Reference copies of the camera images.
  std::vector<array_3*> data_;
  int ref_;
  mutable boost::mutex m_;

  // window variables
  Display *dpy_;
  Window win_;

  void sleep();
  void wait_for_data();
  void draw_image(blitz::Array<float, 2>&);
  void setup_window();
public:
  monitor() : dpy_(0), win_(0) {std::cout << "Image monitor starting\n";};

  /// Tell the monitor object to display images in an emergence object.
  template<typename T>
  void set_images(const emergence<T>& e) {
    boost::mutex::scoped_lock l (m_);
    modified_=true;
    for(typename emergence<T>::iterator i=e.begin(); i!=e.end(); ++i)
      data_.push_back(&(*i)->get_image());
    std::cout << "Monitoring " << data_.size() << " images" << endl;
  };

  /// Tell the monitor object to display images in an emergence object.
  template<typename T>
  void set_images(const emergence<T>& e, int ref) {
    boost::mutex::scoped_lock l (m_);
    modified_=true;
    for(typename emergence<T>::const_iterator i=e.begin(); 
	i!=e.end(); ++i)
      data_.push_back(&(*i)->get_image());
    ref_=ref;
    std::cout << "Monitoring " << data_.size() << " images" << endl;
  };

  /// Clear images.
  void clear_images() {
    boost::mutex::scoped_lock l (m_);
    modified_=true;
    data_.clear();
    std::cout << "Disabling image monitoring." << endl;
  };

  ///  Main loop of the thread.
  void operator() ();
};

#else

// define a dummy class if we have no X11
class mcrx::monitor {
public:
  template<typename T>
  void set_images(const emergence<T>& e) {};
  template<typename T>
  void set_images(const emergence<T>& e, int ref) {};
  void clear_images() {};
  void operator() () {};
};

#endif

#endif
